import { toastValidateError } from "./tools";
const { StatusBar, Platform, DeviceEventEmitter } = require('react-native');
const moment = require('moment');
const { Toast } = require('antd-mobile');
import Validator from "./Validator";
import T from "./T";
let instance = null;
class Request {
    static getApi() {
        return Request.getInstance().Api;
    }
    ;
    static init(api, debug = true, timeout = 30 * 1000, errorOptions = {}) {
        Request.getInstance().Api = api;
        Request.getInstance().debug = debug;
        Request.getInstance().timeout = timeout;
        Request.getInstance().errorOptions = errorOptions;
    }
    static getInstance() {
        if (!instance) {
            instance = new Request();
        }
        return instance;
    }
    static checkResponse(response) {
        Request.setNetworkActivityIndicatorVisible(false);
        return response.json().then(d => d).catch(e => true);
    }
    ;
    static post(url, params, inApp = true) {
        Request.setNetworkActivityIndicatorVisible(true);
        const apiUrl = inApp ? Request.getInstance().Api.HOST + url : url;
        return Request.timeout(Request.getInstance().timeout, fetch(apiUrl, {
            method: 'POST',
            headers: Request.makeHeaders(params),
            body: Request.makeFormData(params)
        })).then((data) => {
            Request.setNetworkActivityIndicatorVisible(false);
            if (data.ok === true) {
                return Request.checkResponse(data);
            }
            else {
                return data.json().then(Request.errorOption);
            }
        }).then((data) => {
            Request.log('%c 网络请求响应 ', 'color:blue', apiUrl, data);
            return data;
        }).catch((e) => {
            Request.setNetworkActivityIndicatorVisible(false);
            Request.LogError(e, url);
            return false;
        });
    }
    static del(url, params, inApp = true) {
        Request.setNetworkActivityIndicatorVisible(true);
        const apiUrl = inApp ? Request.getInstance().Api.HOST + url + Request.makeQueryString(params) : url;
        return Request.timeout(Request.getInstance().timeout, fetch(apiUrl, {
            method: 'DELETE',
            headers: Request.makeHeaders(params),
        })).then((data) => {
            Request.setNetworkActivityIndicatorVisible(false);
            if (data.ok === true) {
                return Request.checkResponse(data);
            }
            else {
                return data.json().then(Request.errorOption);
            }
        }).then((data) => {
            Request.log('%c 网络请求响应 ', 'color:blue', apiUrl, data);
            return data;
        }).catch((e) => {
            Request.setNetworkActivityIndicatorVisible(false);
            Request.LogError(e, apiUrl);
            return false;
        });
    }
    static put(url, params, inApp = true) {
        Request.setNetworkActivityIndicatorVisible(true);
        const apiUrl = inApp ? Request.getInstance().Api.HOST + url : url;
        return Request.timeout(Request.getInstance().timeout, Request.timeout(Request.getInstance().timeout, fetch(apiUrl, {
            method: 'PUT',
            headers: Request.makeHeaders(params),
            body: Request.makeFormData(params)
        }))).then((data) => {
            Request.setNetworkActivityIndicatorVisible(false);
            if (data.ok === true) {
                return Request.checkResponse(data);
            }
            else {
                return data.json().then(Request.errorOption);
            }
        }).then((data) => {
            Request.log('%c 网络请求响应 ', 'color:blue', apiUrl, data);
            return data;
        }).catch((e) => {
            Request.setNetworkActivityIndicatorVisible(false);
            Request.LogError(e, apiUrl);
            return false;
        });
    }
    static get(url, params, inApp = true) {
        Request.setNetworkActivityIndicatorVisible(true);
        let apiUrl = inApp ? Request.getInstance().Api.HOST + `${url}` + Request.makeQueryString(params) : `${url}` + Request.makeQueryString(params);
        apiUrl = encodeURI(apiUrl);
        return Request.timeout(Request.getInstance().timeout, fetch(apiUrl, {
            method: 'GET',
            headers: Request.makeHeaders(params),
        })).then((data) => {
            Request.setNetworkActivityIndicatorVisible(false);
            if (data.ok === true) {
                return Request.checkResponse(data);
            }
            else {
                return data.json().then(Request.errorOption);
            }
        }).then((data) => {
            Request.log('%c 请求成功', 'color:green', apiUrl, data);
            return data;
        }).catch((e) => {
            Request.setNetworkActivityIndicatorVisible(false);
            Request.LogError(e, apiUrl);
            return false;
        });
    }
    static checkImageUrl(url) {
        if (!url)
            return '';
        if (typeof url === 'string') {
            if (Validator.validator(url, Validator.urlReg)) {
                return url;
            }
            else {
                return Request.getInstance().Api.HOST + url;
            }
        }
        if (Validator.validator(url.uri, Validator.urlReg)) {
            return url;
        }
        else {
            return Object.assign({}, url, { uri: Request.getInstance().Api.HOST + url.uri });
        }
    }
    static setNetworkActivityIndicatorVisible(active) {
        if (Platform.OS === 'ios') {
            StatusBar.setNetworkActivityIndicatorVisible(active);
        }
    }
}
Request.makeQueryString = (params) => {
    if (!params) {
        return '';
    }
    let query = [];
    for (let key in params) {
        if (key === 'Authorization')
            continue;
        if (key === 'Content-Type')
            continue;
        if (!params.hasOwnProperty(key)) {
            continue;
        }
        query.push(`${key}=${params[key]}`);
    }
    if (query.length > 0) {
        return '?' + query.join('&');
    }
    else {
        return '';
    }
};
Request.makeFormData = (params) => {
    const formData = new FormData();
    for (let key in params) {
        if (!params.hasOwnProperty(key)) {
            continue;
        }
        if (key === 'Authorization')
            continue;
        if (key === 'Content-Type')
            continue;
        if (key === 'params') {
            return JSON.stringify(params['params']);
        }
        formData.append(key, params[key]);
    }
    return formData;
};
Request.makeHeaders = (params, timestamp) => {
    if (params && params['Authorization']) {
        return new Headers({
            "Content-Type": params['Content-Type'] ? params['Content-Type'] : "application/x-www-form-urlencoded",
            'Authorization': params['Authorization']
        });
    }
    else if (params && params['Content-Type']) {
        return new Headers({
            "Content-Type": params['Content-Type'] ? params['Content-Type'] : "application/x-www-form-urlencoded",
        });
    }
    return null;
};
Request.LogError = (e, from = null) => {
    if (from) {
        Request.log('%c request error ,the error from:', 'color:red', from, e);
    }
    else {
        Request.log('%c request error ', 'color:red', e);
    }
    if (e.message.toLowerCase().indexOf('unexpected token') !== -1) {
        toastValidateError(null, T('Server error'));
    }
    else {
        toastValidateError(null, e.message);
    }
    return false;
};
Request.log = (...args) => {
    if (Request.getInstance().debug) {
        console.log(...args);
    }
};
Request.timeout = (ms, promise) => {
    if (ms <= 0) {
        return promise;
    }
    else {
        return new Promise(function (resolve, reject) {
            setTimeout(function () {
                reject(new Error(T('Network request time out') + ''));
            }, ms);
            promise.then(resolve, reject);
        });
    }
};
Request.errorOption = (data) => {
    if (data.error && data.error) {
        const error = data.error;
        if (typeof Request.getInstance().errorOptions[error] && typeof Request.getInstance().errorOptions[error] === 'function') {
            typeof Request.getInstance().errorOptions[error](data);
        }
        throw new Error(error + '');
    }
    else if (data.message) {
        throw new Error(data.message);
    }
    else {
        throw new Error(T('Can not connect to server') + '');
    }
};
export default Request;
